<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    
    <title>基于位运算的权限管理 | 王鹏的技术博客</title>
    
    
        <meta property="og:site_name" content="王鹏的技术博客">
    
    
        <meta property="article:author" content="王 鹏">
    
    
        <link rel="icon" href="/mhexo/img/favicon.ico">
    
    
<link rel="stylesheet" href="/mhexo/css/minireset.min.css">

    
<link rel="stylesheet" href="/mhexo/css/all.min.css">

    
<link rel="stylesheet" href="/mhexo/css/csshake.min.css">

    
<link rel="stylesheet" href="/mhexo/css/hljs/lioshi.css">

    
<link rel="stylesheet" href="/mhexo/css/jquery.fancybox.min.css">

    
<link rel="stylesheet" href="/mhexo/styl/main.css">

    
<script src="/mhexo/js/jquery.min.js"></script>

    
<script src="/mhexo/js/highlight.min.js"></script>

    
<script src="/mhexo/js/jquery.fancybox.min.js"></script>

    
<script src="/mhexo/js/clipboard.min.js"></script>

<meta name="generator" content="Hexo 5.2.0"></head>
<body>
    <header>
  <div class="outer">
    <div class="inner">
      <h1 class="logo-wrap">
        <a>王鹏的技术博客<b><sup>1.1</sup></b></a>
      </h1>
    </div>
    <div class="inner">
      <nav class="main-nav">
        
          <a href="/mhexo/">首页</a>
        
          <a href="/mhexo/archives">归档</a>
        
          <a href="/mhexo/categories">分类</a>
        
          <a href="/mhexo/tags">标签</a>
        
          <a href="/mhexo/friends">友链</a>
        
          <a href="/mhexo/about">关于</a>
        
          <a target="_blank" rel="noopener" href="https://www.baidu.com">百度</a>
        
      </nav>
    </div>
  </div>
</header>
    <div class="content">
        <section class="outer">
    <article>
        <div class="article-title">
    <h2>
        <a href="/mhexo/2020/12/21/%E5%9F%BA%E4%BA%8E%E4%BD%8D%E8%BF%90%E7%AE%97%E7%9A%84%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86/" class="shake shake-little" title="基于位运算的权限管理">
            
            基于位运算的权限管理
        </a>
    </h2>
    <div class="meta_box">
    
        
        
            
                
        
        <div class="meta meta_auth">
            <img src="/mhexo/img/default.png" alt="head" />
            <p>anonymous</p>
        </div>
    
        
        
        <div class="meta meta_date">
            <i class="fas fa-calendar-alt fa-fw" aria-hidden="true"></i>
            <p>发布于：2020年12月21日</p>
        </div>
    
        <div class="meta meta_update">
            <i class="fas fa-edit fa-fw" aria-hidden="true"></i>
            <p>更新于：2020年12月21日</p>
        </div>
    </div>
    

</div>

        <hr>
        <div class="article-entry">
            
            
            
            <h1 id="基于位运算的权限管理"><a href="#基于位运算的权限管理" class="headerlink" title="基于位运算的权限管理"></a>基于位运算的权限管理</h1><p>位运算基础</p>
<p>位运算，就是直接对二进制位进行与、或、非等逻辑运算。</p>
<p>位运算并不仅限于布尔类型的数据。Int类型数据在内存中也是以二进制数据进行存储的，位计算可以直接对整数在内存中的二进制位进行操作。举个例子，7的二进制是111，6的二进制是110，直接进行与运算“7&amp;6”，相当于二进制进行与运算“111&amp;110”。逐位进行与运算，运算结果110，转化为十进制是6，因此运算结果7&amp;6=6。所有的编程语言都提供了位运算符，你可以用不同的语言编写上述计算，结果都一致。</p>
<p>位运算可以用于权限管理，每一个二进制位来表示是否拥有某个权限。<a target="_blank" rel="noopener" href="https://blog.oonne.com/site/blog?id=50">Linux中的文件权限</a>就是用位计算实现的，需要控制读、写、执行3个权限，仅需用3位二进制数来表示：</p>
<table>
<thead>
<tr>
<th>二进制</th>
<th>十进制</th>
<th>权限</th>
</tr>
</thead>
<tbody><tr>
<td>读         写         执行</td>
<td></td>
<td></td>
</tr>
<tr>
<td>0         0         0</td>
<td>0</td>
<td>无权限</td>
</tr>
<tr>
<td>0         0         1</td>
<td>1</td>
<td>只可执行</td>
</tr>
<tr>
<td>0         1         0</td>
<td>2</td>
<td>只可写</td>
</tr>
<tr>
<td>0         1         1</td>
<td>3</td>
<td>可写可执行</td>
</tr>
<tr>
<td>1         0         0</td>
<td>4</td>
<td>只可读</td>
</tr>
<tr>
<td>1         0         1</td>
<td>5</td>
<td>可读可执行</td>
</tr>
<tr>
<td>1         1         0</td>
<td>6</td>
<td>可读可写</td>
</tr>
<tr>
<td>0         0         0</td>
<td>7</td>
<td>可读可写可执行</td>
</tr>
</tbody></table>
<p>下文将以此为例子，介绍位计算权限控制的原理。</p>
<p>权限管理的实现</p>
<p>校验权限：与运算</p>
<p>把需要校验的权限数值和当前的权限数值进行与运算，用来判断是否拥有某个权限。如果运算结果是被校验的权限值，则说明有这个权限；如果运算结果是0，则说明没有权限。</p>
<p>举个例子，写入的权限是2（010），判断权限6（110）有没有写入权限：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">二进制：110 &amp; 010 &#x3D; 010</span><br><span class="line">十进制：6 &amp; 2 &#x3D; 2</span><br></pre></td></tr></table></figure>

<p>返回结果是2，说明权限6包含了写入的权限2。</p>
<p>再判断权限4（100）有没有写入权限：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">二进制：100 &amp; 010 &#x3D; 000</span><br><span class="line">十进制：4 &amp; 2 &#x3D; 0</span><br></pre></td></tr></table></figure>

<p>返回结果是0，说明权限4不包含写入权限2。</p>
<p>添加权限：或运算</p>
<p>把需要添加的权限数值和当前的权限数值进行或运算，可以添加权限。</p>
<p>举个例子，给只读的权限4（100）增加写入2（010）权限：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">二进制：100 | 010 &#x3D; 110</span><br><span class="line">十进制：4 | 2 &#x3D; 6</span><br></pre></td></tr></table></figure>

<p>运算的结果已经变成可读可写6了。</p>
<p>如果对原本已经有的权限进行或运算也没关系，比如可以给可读可写的权限6（110）增加写入权限2（010）：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">二进制：110 | 010 &#x3D; 110</span><br><span class="line">十进制：6 | 2 &#x3D; 6</span><br></pre></td></tr></table></figure>

<p>原本的权限不会受到任何影响。</p>
<p>去除权限：非运算</p>
<p>把需要去除的权限数值和当前的权限数值进行或运算，可以去除权限。</p>
<p>举个例子，把可读可写的权限6（110）去除写入2（010）权限：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">二进制：110 ^ 010 &#x3D; 100</span><br><span class="line">十进制：6 ^ 2 &#x3D; 4</span><br></pre></td></tr></table></figure>

<p>运算的结果已经变成只读4了。</p>
<p>不能对原本就没有的权限进行非运算。</p>
<p>总结</p>
<p>位运算实现的权限控制，具有运算速度快、节省存储空间、兼容所有的编程语言等优点，在软件系统架构中经常使用。</p>
<p>位运算也有一些局限性。随着权限数量的增加，数据长度变长，可读性会下降。受限于储存和运算位数限制，权限数存在上限，比如32位操作系统的权限就不能多于32个。</p>

        </div>
        <div class="article-copyright">
            
    <blockquote>
        <p>
            版权声明：本文为「子曰无衣」的原创文章，博客内容遵循 署名-非商业性使用-相同方式共享 协议。<br>本文永久链接是：https://wangpdizhi.gitee.io/mhexo/2020/12/21/%E5%9F%BA%E4%BA%8E%E4%BD%8D%E8%BF%90%E7%AE%97%E7%9A%84%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86/
        </p>
    </blockquote>


        </div>
    </article>
    

    <section id="toc-div" >
        <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%9F%BA%E4%BA%8E%E4%BD%8D%E8%BF%90%E7%AE%97%E7%9A%84%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86"><span class="toc-text">基于位运算的权限管理</span></a></li></ol>
    </section>
    <section id="gohome" style="display: none;"><a>顶</a></section>

    <script>
        function get_top_by_link(link){
            var hnid = "#" + $(link).attr("data");
            if ($(hnid).length > 0){
                return $(hnid).offset().top;
            }else{
                return 0;
            }
        }
        //go to hn
        function gotohn(link){
            $("html,body").animate({scrollTop: get_top_by_link(link) }, 300);
        }
        //页面滚动
        function update(){
            var scrollH = $(window).scrollTop();
            if($(".toc-link")){
                $(".toc-link").each(function(i,link){
                    var mdHeight = get_top_by_link(link);
                    if(mdHeight <= scrollH + 40){
                        //高亮导航菜单
                        $('.toc-link').removeClass('on');
                        $(link).addClass('on');
                    }
                });
            }
            //返回顶部显隐
            if(scrollH < 200){
                $("#gohome").css("display","none");
            }else{
                $("#gohome").css("display","block");
            }
        }
        $(function(){
            //修复部分锚点从属关系
            if($("#toc-div >li").length > 0){
                $("#toc-div >li").appendTo($("#toc-div >ol:first"));
            }
            //返回顶部
            $('#gohome').click(function(){
                $("html,body").animate({scrollTop: 0}, 300);
                return false;
            })
            //遍历锚点
            $(".toc-link").each(function(i,link){
                $(link).attr("data",$(link).attr('href').substring(1));
                $(link).attr("href","javascript:void(0);");
                $(link).attr("onclick","gotohn(this);");
            })
            //绑定滚动事件
            $(window).bind('scroll', update);
            //初始化toc
            var first_toc = $(".toc-link")[0];
            var first_scroll = get_top_by_link(first_toc);
            var window_scroll = $(window).scrollTop();
            if(window_scroll <= first_scroll){
                $(first_toc).addClass('on');
            }
        })
    </script>

</section>
    </div>
    <footer>
    <div class="outer">
        <div class="inner">
            Powered by <a href="http://prowiki.demopage.icu/" target="_blank">ProWiki</a>
            &copy;2020 子曰无衣<br>
            <a target="_blank" rel="noopener" href="http://beian.miit.gov.cn/">冀ICP备00000000号</a>
        </div>
    </div>
</footer>

<script src="/mhexo/js/custom.js"></script>


    <script>onload_content();</script>

</body>
</html>
